using System.IO;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;

namespace PpSmsSender
{
    public class HttpSender : ICertificatePolicy
    {
        #region ICertificatePolicy Members
        public bool CheckValidationResult(ServicePoint sp, X509Certificate certificate, WebRequest request, int error)
        {
            return true;
        }
        #endregion

        public static string Get(string httpPayload, Encoding enc)
        {
            HttpWebResponse responseOut = null;
            return Request(httpPayload, enc, -1, null, out responseOut);
        }

        public static string Post(string httpPayload, string postData, Encoding enc)
        {
            HttpWebResponse responseOut = null;
            return Request(httpPayload, enc, -1, postData, out responseOut);
        }


        public static string Request(string url, Encoding enc, int timeout, string PostData, out HttpWebResponse responseOut)
        {
            string uid;
            string passw;
            url = ExtractUidPassw(url, out uid, out passw);

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            //string proxy = null;
            req.Headers.Add("Pragma", "no-cache");
            req.ServicePoint.Expect100Continue = false; //Disable stupid feature

            if (timeout > -1)
            {
                req.Timeout = timeout;
            }
            if (uid != null)
            {
                req.Credentials = new NetworkCredential(uid, passw);
            }

            //req.Proxy = new WebProxy(proxy, true); // ignore for local addresses
            //req.CookieContainer = new CookieContainer(); // enable cookies


            // ServicePointManager.CertificatePolicy is obsoleted, but is the only thing that works on both windows and mono.
            //Needed to avoid errors from homegrown SSL cert.
#pragma warning disable 612,618
            ICertificatePolicy oldPolicy = ServicePointManager.CertificatePolicy;
            ServicePointManager.CertificatePolicy = new HttpSender();
#pragma warning restore 612,618

            req.Method = "GET";
            if (PostData != null)
            {
                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";

                Encoding postDataEnc = enc ?? Encoding.GetEncoding("iso-8859-1");

                string data = PostData;

                var buffer = postDataEnc.GetBytes(data);

                req.ContentLength = buffer.Length;
                Stream reqst = req.GetRequestStream(); // add form data to request stream
                reqst.Write(buffer, 0, buffer.Length);
                reqst.Flush();
                reqst.Close();
            }

            responseOut = (HttpWebResponse)req.GetResponse();

#pragma warning disable 612,618
            ServicePointManager.CertificatePolicy = oldPolicy;
#pragma warning restore 612,618

            Stream resst = responseOut.GetResponseStream();
            if (resst == null)
            {
                return null;
            }
            string characterSet = responseOut.CharacterSet ?? "iso-8859-1";

            enc = Encoding.GetEncoding(characterSet);
            StreamReader sr = new StreamReader(resst, enc, true);
            return sr.ReadToEnd();
        }

        public static string ExtractUidPassw(string url, out string uid, out string passw)
        {
            int startofServer = url.IndexOf("://", System.StringComparison.Ordinal) + 3;
            int indexOfAt = url.IndexOf("@", System.StringComparison.Ordinal);
            int endOfServer = url.IndexOf("/", startofServer, System.StringComparison.Ordinal);
            int indexOfColon = url.IndexOf(":", startofServer, System.StringComparison.Ordinal);

            passw = "";
            uid = null;
            if (indexOfAt < 0)
                return url;

            if (indexOfAt < endOfServer || (indexOfAt > 0 && endOfServer < 0))
            {
                if (indexOfColon < 0 || indexOfColon > indexOfAt)
                {
                    indexOfColon = indexOfAt;
                }
                uid = url.Substring(startofServer, indexOfColon - startofServer);
                if (indexOfColon != indexOfAt)
                {
                    passw = url.Substring(indexOfColon + 1, indexOfAt - indexOfColon - 1);
                }
                url = url.Replace(uid + ":" + passw + "@", "");
            }
            return url;
        }
    }
}